home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / vatpkt.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  8KB  |  334 lines

  1. /*
  2.  
  3.          VAT packet interconversion routines
  4.  
  5. */
  6.  
  7. #include "speakfree.h"
  8. #include "vat.h"
  9. #include <pwd.h>
  10. #include <sys/param.h>
  11.  
  12. static audio_descr_t adt[] = {
  13. /* enc       sample ch */
  14.   {AE_PCMU,  8000, 1},    /*  0 PCMU */
  15.   {AE_MAX,   8000, 1},    /*  1 1016 */
  16.   {AE_MAX,    0, 1},    /*  2 G721 32 kb/s CCITT ADPCM */
  17.   {AE_GSM,   8000, 1},    /*  3 GSM */
  18.   {AE_MAX,    0, 1},    /*  4 G723 24 kb/s CCITT ADPCM */
  19.   {AE_MAX,    0, 1},    /*  5 unassigned */
  20.   {AE_MAX,    0, 1},    /*  6 unassigned */
  21.   {AE_MAX,    0, 1},    /*  7 unassigned */
  22.   {AE_MAX,    0, 1},    /*  8 unassigned */
  23.   {AE_MAX,    0, 1},    /*  9 unassigned */
  24.   {AE_MAX,    0, 1},    /* 10 unassigned */
  25.   {AE_MAX,    0, 1},    /* 11 unassigned */
  26.   {AE_MAX,    0, 1},    /* 12 unassigned */
  27.   {AE_MAX,    0, 1},    /* 13 unassigned */
  28.   {AE_MAX,    0, 1},    /* 14 unassigned */
  29.   {AE_MAX,    0, 1},    /* 15 unassigned */
  30.   {AE_MAX,    0, 1},    /* 16 unassigned */
  31.   {AE_MAX,    0, 1},    /* 17 unassigned */
  32.   {AE_MAX,    0, 1},    /* 18 unassigned */
  33.   {AE_MAX,    0, 1},    /* 19 unassigned */
  34.   {AE_MAX,    0, 1},    /* 20 unassigned */
  35.   {AE_MAX,    0, 1},    /* 21 unassigned */
  36.   {AE_MAX,    0, 1},    /* 22 unassigned */
  37.   {AE_MAX,    0, 1},    /* 23 unassigned */
  38.   {AE_MAX,    0, 1},    /* 24 unassigned */
  39.   {AE_MAX,    0, 1},    /* 25 unassigned */
  40.   {AE_MAX,    0, 1},    /* 26 L16, 16000 samples/sec */
  41.   {AE_MAX,    0, 1},    /* 27 L16, 44100 samples/sec, 2 channels */
  42.   {AE_LPC,   8000, 1},    /* 28 LPC, 4 frames */
  43.   {AE_LPC,   8000, 1},    /* 29 LPC, 1 frame */
  44.   {AE_IDVI,  8000, 1},    /* 30 32 kb/s Intel DVI ADPCM */
  45.   {AE_MAX,    0, 1},    /* 31 unassigned */
  46. };
  47.  
  48. /*  ISVAT  --  Determine if this is a parseable VAT format packet.
  49.            If so, convert it to an equivalent sound buffer.  */
  50.  
  51. int isvat(pkt, len)
  52.   unsigned char *pkt;
  53.   int len;
  54. {
  55.     int findex = pkt[1] & VATHF_FMTMASK;
  56.     soundbuf *s = (soundbuf *) pkt;
  57.  
  58.     /* Validate (as much as possible) whether this is a VAT packet
  59.        that we're able to translate. */
  60.  
  61.     if (((pkt[0] & 0xC0) == 0) && ((pkt[1] & 0x60) == 0) /* &&
  62.     (adt[findex].encoding != AE_MAX) */
  63.     ) {
  64.  
  65.     struct soundbuf sb;
  66.     unsigned char *payload;
  67.     int paylen;
  68.  
  69. /*fprintf(stderr, "VAT Ver = %d, nsid = %d, ts = %d, format = %d confid = %d, tstamp = %ld\n",
  70.     pkt[0] >> 6, pkt[0] & NSID_MASK, !!(pkt[1] & VATHF_NEWTS), findex,
  71.     (((unsigned int) pkt[2]) << 8) | pkt[3],
  72.     (((unsigned long) pkt[4]) << 24) |
  73.     (((unsigned long) pkt[5]) << 16) |
  74.     (((unsigned long) pkt[6]) <<  8) |
  75.     (((unsigned long) pkt[7]) <<  0));
  76. */
  77.  
  78.     payload = pkt + (8 + 4 * (pkt[0] & NSID_MASK)); /* Payload start */
  79.     paylen = len - ((8 + 4 * (pkt[0] & NSID_MASK))); /* Payload length */
  80.     sb.compression = fProtocol;
  81.     sb.buffer.buffer_len = 0;
  82.  
  83. #ifdef NEEDED
  84.     /* Fake a VAT unique host name from the conference identifier. */
  85.  
  86.         sprintf(sb.sendinghost, ".VAT:%02X%02X",
  87.         pkt[2], pkt[3]);
  88. #else
  89.         strcpy(sb.sendinghost, ".VAT");
  90. #endif
  91.  
  92.     switch (adt[findex].encoding) {
  93.  
  94.         case AE_PCMU:
  95.         sb.buffer.buffer_len = paylen;
  96.         bcopy(payload, sb.buffer.buffer_val, paylen);
  97.         break;
  98.  
  99.         case AE_GSM:
  100.         sb.buffer.buffer_len = paylen + sizeof(short);
  101.         bcopy(payload, sb.buffer.buffer_val + 2, paylen);
  102.         *((short *) sb.buffer.buffer_val) =
  103.             htons((short) ((((long) paylen) * 160) / 33));
  104.         sb.compression |= fCompGSM;
  105.         break;
  106.  
  107.         case AE_IDVI:
  108.         bcopy(payload + 4, sb.buffer.buffer_val, paylen - 4);
  109.         bcopy(payload, sb.buffer.buffer_val + (paylen - 4), 3);
  110.         sb.buffer.buffer_len = paylen - 1;
  111.         if (adt[findex].sample_rate == 8000) {
  112.             sb.compression |= fCompADPCM;
  113.         } else {
  114. #ifdef NEEDED
  115.  
  116.             /* Bogus attempt to convert sampling rate.    We
  117.                        really need to do this in linear mode, which isn't
  118.                supported on all SPARCs.  This is better than
  119.                nothing, though. */
  120.  
  121.             int inc = adt[findex].sample_rate / 8000, i;
  122.             unsigned char *in = (unsigned char *) sb.buffer.buffer_val,
  123.                   *out = (unsigned char *) sb.buffer.buffer_val;
  124.  
  125.             adpcmdecomp(&sb);
  126.             for (i = 0; i < (paylen - 4) / inc; i++) {
  127.             *out++ = *in;
  128.             in += inc;
  129.             }
  130.             sb.buffer.buffer_len /= inc;
  131. #endif
  132.         }
  133.         break;
  134.  
  135.         case AE_LPC:
  136.         sb.buffer.buffer_len = paylen + sizeof(short);
  137.         {   int i;
  138.             unsigned char *in = payload,
  139.                   *out = (unsigned char *) sb.buffer.buffer_val + 2;
  140.  
  141.             for (i = 0; i < paylen / 14; i++) {
  142.             bcopy(in, out, 3);
  143.             out[3] = 0;
  144.             bcopy(in + 3, out + 4, 10);
  145.             in += 14;
  146.             out += 14;
  147.             }
  148.         }
  149.         *((short *) sb.buffer.buffer_val) =
  150.             htons((short) ((((long) paylen) * LPC_FRAME_SIZE) / 14));
  151.         sb.compression |= fCompLPC;
  152.         break;
  153.  
  154.         case AE_L16:
  155.         if (adt[findex].channels == 1) {
  156.             int i, j, k;
  157.         
  158.             for (i = j = k = 0; i < (paylen / 8); i++) {
  159.             if ((k & 3) != 2  && ((i % 580) != 579)) {
  160.                 sb.buffer.buffer_val[j++] =
  161.                 audio_s2u((((unsigned short *) payload)[i * 4]));
  162.             }
  163.             k = (k + 1) % 11;
  164.             }
  165.             sb.buffer.buffer_len = j;
  166.         } else if (adt[findex].channels == 2) {
  167.             int i, j, k;
  168.         
  169.             for (i = j = k = 0; i < (paylen / 16); i++) {
  170.             if ((k & 3) != 2  && ((i % 580) != 579)) {
  171.                 sb.buffer.buffer_val[j++] =
  172.                 audio_s2u(((((unsigned short *) payload)[i * 8]) +
  173.                        (((unsigned short *) payload)[i * 8 + 1])) / 2);
  174.             }
  175.             k = (k + 1) % 11;
  176.             }
  177.             sb.buffer.buffer_len = j;
  178.         }
  179.         break;
  180.  
  181.         default:
  182.         /* Unknown compression type. */
  183.         sb.buffer.buffer_len = 0;
  184.         break;
  185.     }
  186.     bcopy(&sb, pkt, (int) (((sizeof sb - BUFL)) + sb.buffer.buffer_len));
  187.     return TRUE;
  188.     }
  189.     return FALSE;
  190. }
  191.  
  192. /*  VATOUT  --    Convert a sound buffer into a VAT packet, given the
  193.         timestamp for the next packet sent to this connection.    */
  194.  
  195. int vatout(sb, ssrc_i, timestamp_i, spurt)
  196.   soundbuf *sb;
  197.   unsigned long ssrc_i;
  198.   unsigned long timestamp_i;
  199.   int spurt;
  200. {
  201.     soundbuf rp;
  202.     char *pkt = (char *) &rp;
  203.     LONG pl = 0;
  204.  
  205.     pkt[0] = 0;
  206.  
  207.     pkt[1] = spurt ? 0x80 : 0;
  208.  
  209.     pkt[2] = ssrc_i & 0xFF;
  210.     pkt[3] = (ssrc_i >> 8) & 0xFF;
  211.  
  212.     *((long *) (pkt + 4)) = htonl(timestamp_i);
  213.  
  214.     if (sb->compression & fCompGSM) {
  215.     pkt[1] |= VAT_AUDF_GSM;
  216.     bcopy(sb->buffer.buffer_val + 2, pkt + 8,
  217.           (int) sb->buffer.buffer_len - 2);
  218.     pl = (sb->buffer.buffer_len - 2) + 8;
  219.  
  220.     } else if (sb->compression & fCompADPCM) {
  221.     pkt[1] |= VAT_AUDF_IDVI;
  222.     bcopy(sb->buffer.buffer_val, pkt + 8 + 4,
  223.           (int) sb->buffer.buffer_len - 3);
  224.     bcopy(sb->buffer.buffer_val + ((int) sb->buffer.buffer_len - 3),
  225.           pkt + 8, 3);
  226.     pkt[8 + 3] = 0;
  227.     pl = (sb->buffer.buffer_len + 1) + 8;
  228.  
  229.     } else if (sb->compression & fCompLPC) {
  230.     int n = (int) ((sb->buffer.buffer_len - 2) / 14);
  231.     int i;
  232.     char *cp = pkt + 8, *sp = sb->buffer.buffer_val + 2;
  233.  
  234.     pkt[1] |= VAT_AUDF_LPC4;
  235.     pl = 8;
  236.     for (i = 0; i < n; i++) {
  237.         bcopy(sp, cp, 3);
  238.         bcopy(sp + 4, cp + 3, 10);
  239.         sp += 14;
  240.         cp += 14;
  241.         pl += 14;
  242.     }
  243.  
  244.     } else {    /* Uncompressed PCMU samples */
  245. #if (VAT_AUDF_MULAW8 != 0)
  246.     pkt[1] |= VAT_AUDF_MULAW8;
  247. #endif
  248.     bcopy(sb->buffer.buffer_val, pkt + 8,
  249.         (int) sb->buffer.buffer_len);
  250.     pl = (int) sb->buffer.buffer_len + 8;
  251.     }
  252.     if (pl > 0) {
  253.     bcopy(pkt, (char *) sb, (int) pl);
  254.     }
  255.     return pl;
  256. }
  257.  
  258. /*  MAKEVATID  --  Create VAT ID packet.  */
  259.  
  260. int makeVATid(vp, ssrc_i)
  261.   char **vp;
  262.   unsigned long ssrc_i;
  263. {
  264.     char *sp = NULL, *cp = NULL;
  265.     struct passwd *pw;
  266.     char s[256];
  267.     int l = 0;
  268.  
  269.     /* Watch as we make increasingly desperate attempts to
  270.        obtain the user's full name. */
  271.  
  272.     sp = getenv("SPEAKFREE_ID");
  273.     if (sp != NULL && strlen(sp) > 0) {
  274.         char *ep = strchr(sp, ':');
  275.     if (ep != NULL) {
  276.         *ep = 0;
  277.     }
  278.     }
  279.  
  280.     if (sp == NULL) {
  281.     pw = getpwuid(getuid());
  282.     if (pw != NULL) {
  283.         if (pw->pw_gecos != NULL) {
  284.         strcpy(s, pw->pw_gecos);
  285.         sp = s;
  286.         } else if (pw->pw_name != NULL) {
  287.         char hn[MAXHOSTNAMELEN];
  288.  
  289.         hn[0] = 0;
  290.         gethostname(hn, sizeof hn);
  291.                 sprintf(s, "%s@%s", pw->pw_name, hn);
  292.         sp = s;
  293.         }
  294.     }
  295.     }
  296.  
  297.     if (sp == NULL) {
  298.         if ((sp = getenv("SPEAKFREE_CNAME")) != NULL && strlen(sp) > 0) {
  299.             if (sp[0] == '*') {
  300.         sp++;
  301.         }
  302.     }
  303.     }
  304.  
  305.     if (sp == NULL) {
  306.         sp = "Unknown User";
  307.     }
  308.  
  309.     cp = malloc(4 + strlen(sp) + 1);
  310.     if (cp != NULL) {
  311.     cp[0] = 0;
  312.     cp[1] = 1;
  313.     cp[2] = ssrc_i & 0xFF;
  314.     cp[3] = (ssrc_i >> 8) & 0xFF;
  315.     strcpy(cp + 4, sp);
  316.     l = 4 + strlen(sp) + 1;
  317.     }
  318.     *vp = cp;
  319.     return l;
  320. }
  321.  
  322. /*  MAKEVATDONE  --  Create VAT "DONE" packet.  */
  323.  
  324. int makevatdone(v, ssrc_i) 
  325.   char *v;
  326.   unsigned long ssrc_i;
  327. {
  328.     v[0] = 0;
  329.     v[1] = 2;
  330.     v[2] = ssrc_i & 0xFF;
  331.     v[3] = (ssrc_i >> 8) & 0xFF;
  332.     return 4;
  333. }
  334.